WordPress Docker 部署 HTTPS 全流程笔记
背景
在阿里云 ECS 上通过 Docker Compose 部署 WordPress,初始只有 HTTP(80端口),需要升级到 HTTPS(443端口),并实现 SSL 证书自动续期。
一、核心架构
1 2 3
| 用户 → 阿里云安全组(80/443) → Nginx(反向代理) → WordPress(FPM) → MariaDB ↓ acme.sh(自动续期)
|
二、完整配置
2.1 docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| services: wordpress: image: wordpress:7.0.1-php8.3-fpm-alpine container_name: wp-course restart: unless-stopped environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: wpuser WORDPRESS_DB_PASSWORD: wpstrongpassword WORDPRESS_DB_NAME: wordpress volumes: - ./html:/var/www/html - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini depends_on: - db
db: image: mariadb:11.8 container_name: wp-db restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: rootpassword MYSQL_DATABASE: wordpress MYSQL_USER: wpuser MYSQL_PASSWORD: wpstrongpassword volumes: - ./db_data:/var/lib/mysql
nginx: image: nginx:alpine container_name: wp-nginx restart: unless-stopped ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro - ./html:/var/www/html - ./cert:/etc/nginx/cert:ro depends_on: - wordpress
acme: image: neilpang/acme.sh:latest container_name: wp-acme restart: unless-stopped entrypoint: ["/entrypoint.sh"] command: daemon environment: - Ali_Key=你的阿里云AccessKey - Ali_Secret=你的阿里云AccessSecret - LE_WORKING_DIR=/acme.sh volumes: - ./acme_data:/acme.sh - ./cert:/acme.sh/certs_out - ./entrypoint.sh:/entrypoint.sh:ro - /root/reload_nginx.sh:/root/reload_nginx.sh:ro - /var/run/docker.sock:/var/run/docker.sock:ro
|
2.2 nginx.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| server { listen 80 default_server; server_name vid.szzhuoju.com; return 301 https://$host$request_uri; }
server { listen 443 ssl default_server; server_name vid.szzhuoju.com;
root /var/www/html; index index.php;
client_max_body_size 2048M;
ssl_certificate /etc/nginx/cert/vid.szzhuoju.com.pem; ssl_certificate_key /etc/nginx/cert/vid.szzhuoju.com.key;
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5;
location / { try_files $uri $uri/ /index.php?$args; }
location ~ \.php$ { fastcgi_pass wordpress:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ { expires 30d; add_header Cache-Control "public, immutable"; }
location ~ /\. { deny all; } }
|
2.3 entrypoint.sh(解决 acme 容器内 docker-cli 缺失问题)
1 2 3 4 5 6 7 8 9 10 11
| #!/bin/sh
if ! command -v docker > /dev/null 2>&1; then echo "Installing docker-cli..." sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories apk add --no-cache docker-cli fi
exec /entry.sh "$@"
|
2.4 reload_nginx.sh(续期后重载 Nginx)
1 2
| #!/bin/bash docker exec wp-nginx nginx -s reload
|
三、部署步骤
3.1 初始化
1 2 3 4 5 6 7 8 9 10 11 12
| mkdir -p ~/wordpress/{html,cert,acme_data,db_data} cd ~/wordpress
chmod +x entrypoint.sh /root/reload_nginx.sh
|
3.2 启动服务
3.3 申请 SSL 证书
1 2 3 4 5 6 7 8 9 10 11 12
| docker exec wp-acme acme.sh --set-default-ca --server letsencrypt
docker exec wp-acme acme.sh --register-account -m [email protected]
docker exec wp-acme acme.sh --issue --dns dns_ali \ -d szzhuoju.com \ --dnssleep 300 \ --server letsencrypt \ --force
|
3.4 安装证书到 Nginx
1 2 3 4
| docker exec wp-acme acme.sh --install-cert -d szzhuoju.com \ --key-file /acme.sh/certs_out/szzhuoju.com.key \ --fullchain-file /acme.sh/certs_out/szzhuoju.com.pem \ --reloadcmd "sh /root/reload_nginx.sh"
|
3.5 验证
1 2 3 4 5
| curl -I https://szzhuoju.com
docker exec wp-acme openssl x509 -enddate -noout -in /acme.sh/certs_out/szzhuoju.com.pem
|
四、踩坑记录
坑1:acme.sh 默认 CA 在国内网络不稳定
- 现象:申请证书时卡在 Pending
- 解决:
--set-default-ca --server letsencrypt 强制使用 Let’s Encrypt
坑2:DNS 验证 TXT 记录添加失败
- 现象:阿里云 API 返回矛盾日志(既说成功又说失败)
- 解决:
--dnssleep 300 给国内 DNS 生效留足缓冲时间
坑3:acme 容器内没有 docker-cli
- 现象:reloadcmd 执行时报
docker: not found
- 解决:通过 entrypoint.sh 自动安装 docker-cli,并挂载 docker.sock
坑4:Alpine 容器没有 bash
- 现象:reloadcmd 用
bash 报 not found
- 解决:改用
sh 执行脚本
坑5:Alpine 官方源国内访问慢
- 现象:apk add 下载超时
- 解决:换中科大镜像源
mirrors.ustc.edu.cn
坑6:entrypoint 路径写错导致容器不断重启
- 现象:容器状态 Restarting (127)
- 解决:用
docker inspect 查看镜像真实入口是 /entry.sh,不是 /usr/local/bin/acme.sh
五、如果从头开始部署带 SSL 的 WordPress
5.1 准备工作
- 域名:提前解析到服务器 IP
- 阿里云:
- 安全组放行 80 和 443 端口
- 创建 RAM 子账号,授予
AliyunDNSFullAccess 权限,获取 AccessKey/Secret
5.2 一键部署
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| mkdir -p ~/wordpress && cd ~/wordpress
docker compose up -d
docker exec wp-acme acme.sh --set-default-ca --server letsencrypt docker exec wp-acme acme.sh --register-account -m [email protected] docker exec wp-acme acme.sh --issue --dns dns_ali \ -d vid.szzhuoju.com \ --dnssleep 300 \ --server letsencrypt \ --force
docker exec wp-acme acme.sh --install-cert -d vid.szzhuoju.com \ --key-file /acme.sh/certs_out/vid.szzhuoju.com.key \ --fullchain-file /acme.sh/certs_out/vid.szzhuoju.com.pem \ --reloadcmd "sh /root/reload_nginx.sh"
|
5.3 对比:从零部署 vs 从 HTTP 升级
| 步骤 |
从零部署 HTTPS |
从 HTTP 升级 |
| nginx.conf |
直接写 443 配置 |
需要从 80 改成 443 |
| 证书申请 |
启动后立即申请 |
启动后立即申请 |
| WordPress 配置 |
安装时直接配 HTTPS |
需要修改 siteurl 和 home |
| 用户体验 |
全程无感 |
可能需要处理混合内容问题 |
5.4 WordPress 后台配置
如果是从 HTTP 升级过来的,还需要在 WordPress 后台修改站点地址:
1 2 3 4 5 6
| docker exec wp-course wp option update siteurl 'https://vid.szzhuoju.com' docker exec wp-course wp option update home 'https://vid.szzhuoju.com'
|
或者在 wp-config.php 中添加:
1 2
| define('WP_HOME', 'https://vid.szzhuoju.com'); define('WP_SITEURL', 'https://vid.szzhuoju.com');
|
六、自动续期机制
1 2 3 4 5 6 7 8 9 10
| acme.sh cron(每天检查4次) ↓ 检测到证书即将过期(<30天) ↓ 通过阿里云 DNS API 自动续签 ↓ 新证书写入 ./cert 目录 ↓ 执行 reload_nginx.sh ↓ Nginx 热加载新证书(零停机)
|
整个过程完全自动化,无需人工干预。
七、维护命令速查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| docker exec wp-acme openssl x509 -enddate -noout -in /acme.sh/certs_out/vid.szzhuoju.com.pem
docker exec wp-acme acme.sh --cron --force
docker exec wp-nginx nginx -s reload
docker exec wp-acme acme.sh --cron --debug
docker compose down && docker compose up -d
docker compose down acme && docker compose up -d acme
|
八、注意事项
- 阿里云 RAM 权限:AccessKey 必须有
AliyunDNSFullAccess,否则续期会失败
- 安全组:确保 443 端口已放行
- 域名解析:域名必须已解析到服务器 IP
- 证书有效期:Let’s Encrypt 证书有效期 90 天,自动续期会在到期前 30 天触发
- 速率限制:同一域名每周最多申请 5 次证书,不要频繁
--force